home *** CD-ROM | disk | FTP | other *** search
/ APDL Eductation Resources / APDL Eductation Resources.iso / programs / astronomy / skyview / !SkyView / c / DaTime next >
Encoding:
Text File  |  1993-08-26  |  5.2 KB  |  155 lines

  1. /********************************************************/
  2. /*                        DaTime                        */
  3. /*  Sundry utility functions concerning date and time.  */
  4. /********************************************************/
  5. #include <math.h>
  6.  
  7. #include "os.h"
  8. #include "coords.h"
  9. #include "menu.h"
  10. #include "sv_header.h"
  11. #include "datime.h"
  12.  
  13. /*    ---------     Global variables.     ----------    */
  14.  
  15. /* Data array for Julian Date algorithm, based on that  */
  16. /* given in NAO Technical Note No. 46 (January 1978):   */
  17.   static int zfun[2][13] = {
  18.     {0, -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333},
  19.     {0, -2, 29, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333}
  20.   };
  21.  
  22. /*     ---------        Functions.       ----------     */
  23.  
  24. /*------------------------------------------------------*/
  25. /* Function to convert time of day in hours to integer  */
  26. /*                  hours and minutes.                  */
  27. /*------------------------------------------------------*/
  28.  void datime_hourmin(REAL time, int *hourptr, int *minptr)
  29. {
  30.   REAL realmin;
  31.  
  32. /* Ensure that result is a valid time.                  */
  33.   if (time <  (REAL)0.0)
  34.   {
  35.     *hourptr = 0;
  36.     *minptr  = 0;
  37.     return;
  38.   }
  39.  
  40.   if (time >= (REAL)24.0)
  41.   {
  42.     *hourptr = 23;
  43.     *minptr  = 59;
  44.     return;
  45.   }
  46.  
  47.   *hourptr   = (int)time;
  48.   realmin = (REAL)60.0 * (time - (REAL)*hourptr) + (REAL)0.5;
  49.   *minptr    = (int)realmin;
  50.  
  51.   return;
  52. }
  53.  
  54. /*------------------------------------------------------*/
  55. /*   Function to calculate the days and fraction of a   */
  56. /*  day since noon GMT on 00/01/1900.  The date is that */
  57. /* specified in the observerstr pointed to by ptr, and  */
  58. /*  the time of day is given by the parameters.  Time   */
  59. /*        offset (time zone) is taken from *ptr.        */
  60. /*------------------------------------------------------*/
  61.   double datime_julian(observerstr *ptr, int hour, int min)
  62. {
  63. /* Based on algorithm in Nautical Almanac Office Tech-  */
  64. /* nical Note No. 46 (January 1978).                    */
  65. /* J = int(365.25*(year-1900)) + zfun[leap][month] +    */
  66. /*     0.5 + day + ut/24                                */
  67. /* where ut is universal time (=GMT) in hours,          */
  68. /*       leap is 1 for a leap year and 0 otherwise,     */
  69. /*   and zfun was defined in the section on global vars.*/
  70.  
  71.   int y = (1461 * (ptr->year - 1900)) / 4;
  72.   double time = (double)hour + (double)min/60.0;
  73.  
  74.   return (double)y +
  75.          (double)zfun[leap(ptr->year)][ptr->month] +
  76.          0.5 +
  77.          (double)ptr->day +
  78.          (time - (double)ptr->offset)/24.0;
  79. }
  80.  
  81. /*------------------------------------------------------*/
  82. /*  Function to calculate local siderial time, for the  */
  83. /* date, time and location specified. Time offset (time */
  84. /*  zone) and longitude are taken from the observerstr  */
  85. /* pointed to by ptr.  Other info is given by params.   */
  86. /*   Result is in radians, in range 0 <= time < 2*PI.   */
  87. /*------------------------------------------------------*/
  88.   REAL datime_siderial(observerstr *ptr, double jul, int hour, int min)
  89. {
  90. /* Based on algorithm in Nautical Almanac Office Tech-  */
  91. /* nical Note 46 (January 1978).                        */
  92.  
  93. /* observerstr fields offset and longit assumed valid.  */
  94.  
  95.   double t   = jul/36525.0;
  96.   double tim = (double)hour + (double)min/60.0
  97.               -(double)ptr->offset;
  98.   double ghaa;
  99.   REAL   lst;
  100.  
  101. /* Get Greenwich Hour Angle of Aries, 0 <= ghaa < 2*PI. */
  102.   ghaa = fmod(99.6910 + 36000.7689*t + 15.0*tim + 360.0, 360.0);
  103.  
  104. /* Get local siderial time, 0 <= lst < 2*PI.            */
  105.   lst = (REAL)ghaa*CONV - ptr->longit;
  106.   if (lst <  ZERO  ) lst += TWO_PI;
  107.   if (lst >= TWO_PI) lst -= TWO_PI;
  108.   if (lst <  ZERO  ) lst  = ZERO;
  109.  
  110.   return lst;
  111. }
  112.  
  113. /*------------------------------------------------------*/
  114. /*  Function to calculate (one) civil time during the   */
  115. /*     day at which the local siderial time equals      */
  116. /*        'sid_time' (which must be in radians).        */
  117. /*------------------------------------------------------*/
  118.   void datime_time_today(REAL sid_time, observerstr *ptr,
  119.                          int *hourptr, int *minptr)
  120. {
  121. /* Hour, min and sid fields of observerstr are assumed  */
  122. /* to be consistent with each other.                    */
  123.  
  124.   REAL siderial_diff;
  125.   REAL solar_diff;
  126.   REAL tim;
  127.  
  128. /* Get sid_time into range 0 <= sid_time < 2*PI.        */
  129.   while (sid_time <  ZERO  ) sid_time += TWO_PI;
  130.   while (sid_time >= TWO_PI) sid_time -= TWO_PI;
  131.   if    (sid_time <  ZERO  ) sid_time  = ZERO;
  132.  
  133. /* Find time difference (in siderial hours) between     */
  134. /* siderial time now and required siderial time.        */
  135. /* Diff is in range -24 < diff < 24                     */
  136.   siderial_diff = (sid_time - ptr->sid)/CONV/(REAL)15.0;
  137.  
  138. /* Convert difference to solar hours.                   */
  139.   solar_diff = SID_TO_SOL * siderial_diff;
  140.  
  141. /* Calculate required civil time in decimal hours.      */
  142.   tim = (REAL)ptr->hour + (REAL)ptr->min/(REAL)60.0 + \
  143.        solar_diff;
  144.  
  145. /* Bring time within range by adding or subtracting one */
  146. /* siderial day, if necessary.                          */
  147.   while (tim <  (REAL) 0.0) tim += (REAL)24.0 * SID_TO_SOL;
  148.   while (tim >= (REAL)24.0) tim -= (REAL)24.0 * SID_TO_SOL;
  149.  
  150. /* Convert tim to integer hours and minutes.            */
  151.   datime_hourmin(tim, hourptr, minptr);
  152.  
  153.   return;
  154. }
  155.